namespace pengpeng {
	export abstract class PPFactory {
		
		protected static NAME: string = "name";
		protected static TEXTURE_ATLAS: string = "TextureAtlas";
        protected static SUB_TEXTURE: string = "SubTexture";
        protected static FORMAT: string = "format";
        protected static IMAGE_PATH: string = "imagePath";
        protected static WIDTH: string = "width";
        protected static HEIGHT: string = "height";
        protected static ROTATED: string = "rotated";
        protected static FRAME_X: string = "frameX";
        protected static FRAME_Y: string = "frameY";
        protected static FRAME_WIDTH: string = "frameWidth";
        protected static FRAME_HEIGHT: string = "frameHeight";
        protected static SCALE: string = "scale";
        protected static X: string = "x";
        protected static Y: string = "y";

		private _textureAtlasDataMap:Map<string, Array<TextureAtlasData>> = new Map<string,Array<TextureAtlasData>>();

		private _textureParser:TextureParser;
        private _dataParser:DataParser;
        private _data:PPData;

		public constructor() {

		}

		protected addTextureAtlasData(data: TextureAtlasData, name: string = null): void {
            if (data) {
                name = name || "default";
                if (name) {
                    const textureAtlasList = this._textureAtlasDataMap[name] ? this._textureAtlasDataMap[name] : (this._textureAtlasDataMap[name] = []);
                    if (textureAtlasList.indexOf(data) < 0) {
                        textureAtlasList.push(data);
                    }
                }
                else {
                    console.warn("Unnamed data.");
                }
            }
            else {
                throw new Error();
            }
        }

		protected _getTextureData(textureAtlasName: string, textureName: string): TextureData {
            textureAtlasName = textureAtlasName || "default" 
            let textureAtlasDataList = this._textureAtlasDataMap[textureAtlasName];
            if (textureAtlasDataList) {
                for (let i = 0, l = textureAtlasDataList.length; i < l; ++i) {
                    const textureData = textureAtlasDataList[i].getTexture(textureName);
                    if (textureData) {
                        return textureData;
                    }
                }
            }
            return null;
        }

		protected abstract _generateTextureAtlasData(textureAtlasData: TextureAtlasData, textureAtlas: any): TextureAtlasData;
		protected parseTextureAtlas(rawData: any, textureAtlas: any, name: string = "default", scale: number = 1.0): TextureAtlasData {
            const textureAtlasData = this._generateTextureAtlasData(null, null);
			if(this._textureParser == null)
			{
				this._textureParser = new pengpeng.TextureParser();
			}
            this._textureParser.parseTextureAtlasData(rawData, textureAtlasData, scale);
            this._generateTextureAtlasData(textureAtlasData, textureAtlas);
            this.addTextureAtlasData(textureAtlasData, name);

            return textureAtlasData;
        }

		public addTextueData(textureConfig:any, textureImage:any):void
		{
			this.parseTextureAtlas(textureConfig, textureImage)
		}

		public addPengPengData(data:any):void
		{
            if(this._dataParser == null)
            {
                this._dataParser = new DataParser();
            }
            this._data = this._dataParser.parse(data);
		}
        
        protected getWorldData(name:string):WorldData
        {
            if(this._data)
            {
                return this._data.worlds[name];
            }
        }
        protected getAssetData(name:string):AssetData
        {
            if(this._data)
            {
                return this._data.assets[name];
            }
        }
		public abstract createWorld(name:string):PPWorld
	}
}